package com.caryguan.demo;

/**
 * @author caryguan
 * @version V1.0
 * @Package com.caryguan.demo
 * @date 2020/10/13 6:19
 */
public class 分数排名 {
    /**
     * 编写一个 SQL 查询来实现分数排名。
     *
     * 如果两个分数相同，则两个分数排名（Rank）相同。请注意，平分后的下一个名次应该是下一个连续的整数值。换句话说，名次之间不应该有“间隔”。
     *
     * +----+-------+
     * | Id | Score |
     * +----+-------+
     * | 1  | 3.50  |
     * | 2  | 3.65  |
     * | 3  | 4.00  |
     * | 4  | 3.85  |
     * | 5  | 4.00  |
     * | 6  | 3.65  |
     * +----+-------+
     * 例如，根据上述给定的 Scores 表，你的查询应该返回（按分数从高到低排列）：
     *
     * +-------+------+
     * | Score | Rank |
     * +-------+------+
     * | 4.00  | 1    |
     * | 4.00  | 1    |
     * | 3.85  | 2    |
     * | 3.65  | 3    |
     * | 3.65  | 3    |
     * | 3.50  | 4    |
     * +-------+------+
     * 重要提示：对于 MySQL 解决方案，如果要转义用作列名的保留字，可以在关键字之前和之后使用撇号。例如 `Rank`
     *
     * 来源：力扣（LeetCode）
     * 链接：https://leetcode-cn.com/problems/rank-scores
     * 著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。
     */
    //最后的结果包含两个部分，第一部分是降序排列的分数，第二部分是每个分数对应的排名。
    //select a.Score  as Score from Scores as a order by a.Score desc
    //比较难的是第二部分。假设现在给你一个分数X，如何算出它的排名Rank呢？
    // 我们可以先提取出大于等于X的所有分数集合H，将H去重后的元素个数就是X的排名。比如你考了99分，但最高的就只有99分，那么去重之后集合H里就只有99一个元素，个数为1，因此你的Rank为1。
    // 先提取集合H：
    //
    //
    // select b.Score from Scores b where b.Score >= X;
    // 我们要的是集合H去重之后的元素个数，因此升级为：
    //
    //
    // select count(distinct b.Score) from Scores b where b.Score >= X as Rank;
    // 而从结果的角度来看，第二部分的Rank是对应第一部分的分数来的，所以这里的X就是上面的a.Score，把两部分结合在一起为：
    //
    //
    // select a.Score as Score,
    // (select count(distinct b.Score) from Scores b where b.Score >= a.Score) as Rank
    // from Scores a
    // order by a.Score DESC
    //
    // 作者：johnbear007
    // 链接：https://leetcode-cn.com/problems/rank-scores/solution/fen-cheng-liang-ge-bu-fen-xie-hui-rong-yi-hen-duo-/
    // 来源：力扣（LeetCode）
    // 著作权归作者所有。商业转载请联系作者获得授权，非商业转载请注明出处。
}